﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;
using Twipler.App.Render.Effect;
using Xunit.Extensions;

namespace UnitTests.App.Render.Effect
{
    public class TweetDecoderTest
    {
        [Theory]
        [InlineData("a")]
        [InlineData(" ")]
        [InlineData("  ")]
        [InlineData("T1 Hello @name how's it going?")]
        [InlineData("@T2 how's it going?")]
        [InlineData("How's it going @T3")]
        [InlineData("How's it going @T3?")]
        public void AlwaysRebuildOriginalString(string text)
        {
            List<TweetSection> result = TweetDecoder.Decode(text);

            Assert.NotNull(result);

            StringBuilder str = new StringBuilder();
            foreach (TweetSection section in result)
                str.Append(section.Text);

            Assert.Equal(text, str.ToString());
        }

        [Theory]
        [InlineData("T1 Hello @name how's it going?")]
        [InlineData("@T2 how's it going?")]
        [InlineData("How's it going @T3")]
        [InlineData("How's it going @T3?")]
        [InlineData("Check out www.this.com link T4")]
        [InlineData("Check out http://www.this.com link T5")]
        [InlineData("http://www.this.com link T6 is awesome!")]
        [InlineData(" http://www.this.com link T11 is awesome!")]
        [InlineData("T7 http://www.this.com")]
        [InlineData("T8 http://www.this.com ")]
        [InlineData("T9 this #code")]
        [InlineData("T10 this #code ")]
        [InlineData("#code T12 this #code ")]
        [InlineData(" #code T13 this #code")]
        [InlineData("#code T14 @name ")]
        [InlineData("T15 #code @name")]
        [InlineData("#code T16 @ ")]
        [InlineData("@code T17 # ")]
        [InlineData("code T18 # ")]
        public void OnlyNormalTextStartsOrEndsWithSpace(string text)
        {
            List<TweetSection> result = TweetDecoder.Decode(text);

            Assert.NotNull(result);

            foreach (TweetSection section in result)
            {
                if (section.SectionType != TweetSectionType.NormalText)
                {
                    Assert.False(section.Text.StartsWith(" "));
                    Assert.False(section.Text.EndsWith(" "));
                }
            }
        }



        [Theory]
        [InlineData(TweetSectionType.NormalText, "a")]
        [InlineData(TweetSectionType.NormalText, "a ")]
        [InlineData(TweetSectionType.NormalText, " a")]
        [InlineData(TweetSectionType.NormalText, " a ")]
        [InlineData(TweetSectionType.NormalText, "this.is")]
        [InlineData(TweetSectionType.NormalText, "Hello world!")]
        [InlineData(TweetSectionType.NormalText, "Hello  world!")]
        [InlineData(TweetSectionType.NormalText, "this http-is tricky")]
        [InlineData(TweetSectionType.NormalText, "this https-is tricky")]
        [InlineData(TweetSectionType.NormalText, "  Hello  world ! ")]
        [InlineData(TweetSectionType.NormalText, "I think https means secure hypertext transfer protocol")]
        [InlineData(TweetSectionType.NormalText, "I think https: means secure hypertext transfer protocol")]
        [InlineData(TweetSectionType.NormalText, "I think https:/ means secure hypertext transfer protocol")]
        [InlineData(TweetSectionType.NormalText, "I think http: means hypertext transfer protocol")]
        [InlineData(TweetSectionType.NormalText, "usually www. starts a web address")]
        [InlineData(TweetSectionType.AtName, "@tanem")]
        [InlineData(TweetSectionType.NormalText, "@")]
        [InlineData(TweetSectionType.NormalText, "@ ")]
        [InlineData(TweetSectionType.NormalText, "a@")]
        [InlineData(TweetSectionType.NormalText, " a@")]
        [InlineData(TweetSectionType.NormalText, "a@")]
        [InlineData(TweetSectionType.HashCode, "#hascode")]
        [InlineData(TweetSectionType.NormalText, "#")]
        [InlineData(TweetSectionType.NormalText, " a# bc # c#")]
        [InlineData(TweetSectionType.Url, "http://twipler.com")]
        [InlineData(TweetSectionType.Url, "www.twipler.com")] 
        [InlineData(TweetSectionType.Url, "https://twipler.com")]
        [InlineData(TweetSectionType.Url, "http:/twipler.com")]
        [InlineData(TweetSectionType.Url, "https:/twipler.com")]
        [InlineData(TweetSectionType.NormalText, "I think http means hypertext transfer protocol")]
        public void OneSection(TweetSectionType type1, string text1)
        {
            List<TweetSection> result = TweetDecoder.Decode(text1);

            Assert.NotNull(result);
            Assert.Equal(result.Count, 1);

            Assert.Equal(result[0].SectionType, type1);
            Assert.Equal(result[0].Text, text1);
        }


        [Theory]
        [InlineData(TweetSectionType.NormalText, "Hello T23 ", TweetSectionType.AtName, "@name")]
        public void TwoSections(TweetSectionType type1, string text1, TweetSectionType type2, string text2)
        {
            List<TweetSection> result = TweetDecoder.Decode(text1 + text2);

            Assert.NotNull(result);
            Assert.Equal(result.Count, 2);

            Assert.Equal(result[0].SectionType, type1);
            Assert.Equal(result[0].Text, text1);

            Assert.Equal(result[1].SectionType, type2);
            Assert.Equal(result[1].Text, text2);
        }

        [Theory]
        [InlineData(TweetSectionType.NormalText, "T1 Hello ", TweetSectionType.AtName, "@name", TweetSectionType.NormalText, " World")]
        [InlineData(TweetSectionType.NormalText, "T2 Hello ", TweetSectionType.AtName, "@name", TweetSectionType.NormalText, "@World")]
        [InlineData(TweetSectionType.HashCode, "#T3", TweetSectionType.NormalText, " name ", TweetSectionType.AtName, "@World")]
        [InlineData(TweetSectionType.AtName, "@T4", TweetSectionType.NormalText,  " name  ", TweetSectionType.AtName, "@World")]
        [InlineData(TweetSectionType.NormalText, "Hello T5 test subject. ", TweetSectionType.AtName, "@name", TweetSectionType.NormalText, "@World")]
        [InlineData(TweetSectionType.NormalText, "Check T6 my link. ", TweetSectionType.Url, "www.example.com", TweetSectionType.NormalText, " it's awesome")]
        [InlineData(TweetSectionType.NormalText, "Check T7 my link. ", TweetSectionType.Url, "www.example.com", TweetSectionType.NormalText, " it's awesome @!")]
        public void ThreeSections(TweetSectionType type1, string text1, TweetSectionType type2, string text2, TweetSectionType type3, string text3)
        {
            List<TweetSection> result = TweetDecoder.Decode(text1 + text2 + text3);

            Assert.NotNull(result);
            Assert.Equal(result.Count, 3);

            Assert.Equal(result[0].SectionType, type1);
            Assert.Equal(result[0].Text, text1);

            Assert.Equal(result[1].SectionType, type2);
            Assert.Equal(result[1].Text, text2);

            Assert.Equal(result[2].SectionType, type3);
            Assert.Equal(result[2].Text, text3);
        }


        [Theory]
        [InlineData(TweetSectionType.AtName, "@T32", TweetSectionType.NormalText, " ", TweetSectionType.Url, "www.example.com", TweetSectionType.NormalText, "   it's awesome")]
        [InlineData(TweetSectionType.AtName, "@T43", TweetSectionType.NormalText, " ", TweetSectionType.Url, "https://www.example.com", TweetSectionType.NormalText, "  it's awesome #")]
        [InlineData(TweetSectionType.Url, "http:/www.T55.com", TweetSectionType.NormalText, " ",  TweetSectionType.Url, "https://www.example.com", TweetSectionType.NormalText, "     it's awesome  @")]
        public void FourSections(TweetSectionType type1, string text1, TweetSectionType type2, string text2, TweetSectionType type3, string text3, TweetSectionType type4, string text4)
        {
            List<TweetSection> result = TweetDecoder.Decode(text1 + text2 + text3 + text4);

            Assert.NotNull(result);
            Assert.Equal(result.Count, 4);

            Assert.Equal(result[0].SectionType, type1);
            Assert.Equal(result[0].Text, text1);

            Assert.Equal(result[1].SectionType, type2);
            Assert.Equal(result[1].Text, text2);

            Assert.Equal(result[2].SectionType, type3);
            Assert.Equal(result[2].Text, text3);

            Assert.Equal(result[3].SectionType, type4);
            Assert.Equal(result[3].Text, text4);
        }

    }
}
